using System;
using System.Collections.Generic;

using IBatisNet.Common;
using IBatisNet.DataMapper;

using log4net;

using GymManager.Exception;
using GymManager.Persistence.VO;

namespace GymManager.Persistence.DAO
{
    /// <summary>
    /// Class responsible by getting information from database about modalities
    /// </summary>
    public class ModalityDAO
    {
        // logger instance
        private ILog _logManager = LogManager.GetLogger(typeof(ModalityDAO));

        /// <summary>
        /// Method responsible by getting a modlaity using its key as fielter
        /// </summary>
        /// <param name="Int32">modality's identifier</param>
        /// <returns>Modality - user value object matching with given identifier</returns>
        /// <see cref="GymManager.Exception.PersistenceException"/>
        public Modality findByKey(Int32 key)
        {
            if (_logManager.IsInfoEnabled)
            {
                _logManager.Info("Begin Method");
            }

            // modality value object to be returned
            Modality modalityResult = null;

            try
            {
                ISqlMapper ibatisMapper = DAOManager.getInstance();
                modalityResult = ibatisMapper.QueryForObject<Modality>("Modality.findByKey", key);
            }
            catch (System.Exception ex)
            {
                _logManager.Error("Error while retrieving modality information", ex);
                throw new PersistenceException("Error while retrieving modality information", ex);
            }

            if (_logManager.IsInfoEnabled)
            {
                _logManager.Info("End Method");
            }

            return modalityResult;
        }

        /// <summary>
        /// Method responsible by getting information about modality in according to a given description
        /// </summary>
        /// <param name="String">modality's description</param>
        /// <returns>Modality - user value object matching with given description</returns>
        /// <see cref="GymManager.Exception.PersistenceException"/>
        public Modality findByDescription(String description)
        {
            if (_logManager.IsInfoEnabled)
            {
                _logManager.Info("Begin Method");
            }

            // modality value object to be returned
            Modality modalityResult = null;

            try
            {
                ISqlMapper ibatisMapper = DAOManager.getInstance();
                modalityResult = ibatisMapper.QueryForObject<Modality>("Modality.findByDescription", description);
            }
            catch (System.Exception ex)
            {
                _logManager.Error("Error while retrieving modality information", ex);
                throw new PersistenceException("Error while retrieving modality information", ex);
            }

            if (_logManager.IsInfoEnabled)
            {
                _logManager.Info("End Method");
            }

            return modalityResult;
        }

        /// <summary>
        /// Method responsible by finding all active modalities
        /// </summary>
        /// <returns>IList - list of all active modalities</returns>        
        /// <see cref="GymManager.Exception.PersistenceException"/>
        public IList<Modality> findAllActive()
        {
            if (_logManager.IsInfoEnabled)
            {
                _logManager.Info("Begin Method");
            }

            // list of modalities found
            IList<Modality> modalityList = null;

            try
            {
                ISqlMapper ibatisMapper = DAOManager.getInstance();
                modalityList = ibatisMapper.QueryForList<Modality>("Modality.findAllActive", null);
            }
            catch (System.Exception ex)
            {
                _logManager.Error("Error while retrieving modality information", ex);
                throw new PersistenceException("Error while retrieving modality information", ex);
            }

            if (_logManager.IsInfoEnabled)
            {
                _logManager.Info("End Method");
            }

            return modalityList;
        }

        /// <summary>
        /// Method responsible by finding all active modalities with schedule needed.
        /// </summary>
        /// <returns>IList - list of all active modalities with schedule</returns>        
        /// <see cref="GymManager.Exception.PersistenceException"/>
        public IList<Modality> findAllActiveWithSchedule()
        {
            if (_logManager.IsInfoEnabled)
            {
                _logManager.Info("Begin Method");
            }

            // list of modalities found
            IList<Modality> modalityList = null;

            try
            {
                ISqlMapper ibatisMapper = DAOManager.getInstance();
                modalityList = ibatisMapper.QueryForList<Modality>("Modality.findAllActiveWithSchedule", null);
            }
            catch (System.Exception ex)
            {
                _logManager.Error("Error while retrieving modality information", ex);
                throw new PersistenceException("Error while retrieving modality information", ex);
            }

            if (_logManager.IsInfoEnabled)
            {
                _logManager.Info("End Method");
            }

            return modalityList;
        }

        /// <summary>
        /// Method responsible by finding modalities using any of its properties
        /// </summary>
        /// <param name="Modality">modality vo filter</param>
        /// <returns>IList - list of modalities retrieved in according to filter</returns>
        /// <see cref="GymManager.Exception.PersistenceException"/>
        public IList<Modality> findByAny(Modality modalityVOFilter)
        {
            if (_logManager.IsInfoEnabled)
            {
                _logManager.Info("Begin Method");
            }

            // list of modalities found
            IList<Modality> modalityList = null;

            try
            {
                ISqlMapper ibatisMapper = DAOManager.getInstance();
                modalityList = ibatisMapper.QueryForList<Modality>("Modality.findByAny", modalityVOFilter);
            }
            catch (System.Exception ex)
            {
                _logManager.Error("Error while retrieving modality information", ex);
                throw new PersistenceException("Error while retrieving modality information", ex);
            }

            if (_logManager.IsInfoEnabled)
            {
                _logManager.Info("End Method");
            }

            return modalityList;
        }

        /// <summary>
        /// Method responsible by adding a new modality to database
        /// </summary>
        /// <param name="Modality">modality information to be saved</param>
        /// <see cref="GymManager.Exception.PersistenceException"/>
        public void create(Modality modalityVO)
        {
            if (_logManager.IsInfoEnabled)
            {
                _logManager.Info("Begin Method");
            }

            try
            {
                ISqlMapper ibatisMapper = DAOManager.getInstance();

                // doing job inside transaction
                using (IDalSession sessionTransaction = ibatisMapper.BeginTransaction())
                {
                    // adding basic modality information
                    ibatisMapper.Insert("Modality.insert", modalityVO);

                    // adding modality plan information
                    foreach (ModalityPlan modalityPlanVO in modalityVO.ModalityPlanList)
                    {
                        // assigning student id
                        modalityPlanVO.ModalityId = modalityVO.Id;

                        // adding modality plan
                        ibatisMapper.Insert("ModalityPlan.insert", modalityPlanVO);
                    }

                    // committing the transaction
                    sessionTransaction.Complete();
                }
            }
            catch (System.Exception ex)
            {
                _logManager.Error("Error while saving modality information", ex);
                throw new PersistenceException("Error while saving modality information", ex);
            }

            if (_logManager.IsInfoEnabled)
            {
                _logManager.Info("End Method");
            }
        }

        /// <summary>
        /// Method responsible by updating a modality to database
        /// </summary>
        /// <param name="Modality">modality information to be saved</param>
        /// <see cref="GymManager.Exception.PersistenceException"/>
        public void update(Modality modalityVO)
        {
            if (_logManager.IsInfoEnabled)
            {
                _logManager.Info("Begin Method");
            }

            try
            {
                ISqlMapper ibatisMapper = DAOManager.getInstance();

                // doing job inside transaction
                using (IDalSession sessionTransaction = ibatisMapper.BeginTransaction())
                {
                    // updating basic modality information
                    ibatisMapper.Update("Modality.update", modalityVO);

                    // adding modality plan information
                    foreach (ModalityPlan modalityPlanVO in modalityVO.ModalityPlanList)
                    {
                        // deciding which operation perform in according to the modality plan identifier
                        if (modalityPlanVO.ModalityId < 0)
                        {
                            // removing modality plans before inserting the updated ones
                            ibatisMapper.Delete("ModalityPlan.delete", modalityPlanVO.Id);
                        }
                        else
                        {
                            if (modalityPlanVO.Id > 0)
                            {
                                ibatisMapper.Update("ModalityPlan.update", modalityPlanVO);
                            }
                            else
                            {
                                // assigning student id
                                modalityPlanVO.ModalityId = modalityVO.Id;
                                ibatisMapper.Insert("ModalityPlan.insert", modalityPlanVO);
                            }
                        }
                    }

                    // committing the transaction
                    sessionTransaction.Complete();
                }
            }
            catch (System.Exception ex)
            {
                _logManager.Error("Error while saving modality information", ex);
                throw new PersistenceException("Error while saving modality information", ex);
            }

            if (_logManager.IsInfoEnabled)
            {
                _logManager.Info("End Method");
            }
        }
    }
}
